import 'package:im_app/im/dao/ImMessageDao.dart';
import 'package:im_app/im/socket/service/RpcPullDataService.dart';
import 'package:logger/logger.dart';

import '../pojo/ImPojo.dart';
import '../socket/dto/business/Message.dart';
import '../socket/dto/business/PullData.dart';
import '../socket/dto/business/PullData2.dart';
import 'BaseService.dart';

class  ImMessageRefService extends BaseService {

  final _logger = Logger(
    printer: PrettyPrinter(),
  );

  Future<List<MessageObject>> pullRefMessages(String userId, List<String> serverIdList) async {
    if (serverIdList.isEmpty) return [];
    List<MessageObject> result = [];

    // 处理有引用的消息
    List<MessageObject> messageObjectList = await _pullMessages(userId, serverIdList);
    messageObjectList = messageObjectList.map((mo)=> RefMessageObject(mo)).toList();
    result.addAll(messageObjectList);
    _logger.i("synData message ref size  ${messageObjectList.length}");
    return result;
  }

  Future<List<MessageObject>> pullCollectRefMessages(String userId, List<CollectInfoItem> collectInfoItems) async {
    if (collectInfoItems.isEmpty) return [];
    List<MessageObject> result = [];

    Set<String>? pulledServerIds = collectInfoItems.map((mo)=>mo.messageId!).toSet();
    ImMessageDao imMessageDao = ImMessageDao();
    List<ImMessage> dbMessages = await imMessageDao.getByServerIdsAndUserId(pulledServerIds, userId);
    Set<String> dbServerIdSet = dbMessages.map((m)=>m.serverId!).toSet();

    // 处理有引用的消息
    Set<String> serverIdSet = pulledServerIds.where((sid)=>!dbServerIdSet.contains(sid)).toSet();
    List<MessageObject> messageObjects = await pullRefMessages(userId, serverIdSet.toList());
    result.addAll(messageObjects);
    _logger.i("synData message ref size ${messageObjects.length}");
    return result;
  }

  Future<List<MessageObject>> _pullMessages(String userId, List<String> serverIdList) async {
    if (serverIdList.isEmpty) return [];

    Set<String> serverIdSet = serverIdList.toSet();
    ImMessageDao imMessageDao = ImMessageDao();
    List<ImMessage> dbMessages = await imMessageDao.getByServerIdsAndUserId(serverIdSet, userId);
    Set<String?> dbServerIdSet = dbMessages.map((m)=>m.serverId).toSet();
    Set<String> noReceiveServerIdSet = serverIdSet.where((sid)=>!dbServerIdSet.contains(sid)).where((s)=>s != null).toSet();

    if (noReceiveServerIdSet.isEmpty) return [];

    List<MessageObject> result = [];

    MessagePullByMessageIdsReq messagePullByMessageIdsReq = new MessagePullByMessageIdsReq(serverMessageIdList: noReceiveServerIdSet.toList());
    RpcPullDataService rpcPullDataService = RpcPullDataService();
    MessageListItem messageListItem = await rpcPullDataService.pullMessageByMessageIds(messagePullByMessageIdsReq);
    List<MessageObject> messageObjectList = messageListItem.messageObjectList.map((mo)=>new RefMessageObject(mo)).toList();
    result.addAll(messageObjectList);

    Set<String> refServerIdSet = new Set();
    for (MessageObject messageObject in messageObjectList) {
      if (messageObject.isRef()) {
        List<String> refServerIds = messageObject.refMessageIds!.split(",");
        refServerIdSet.addAll(refServerIds);
      }
    }

    List<MessageObject> messageObjects2 = await _pullMessages(userId, refServerIdSet.toList());
    result.addAll(messageObjects2);

    return result;
  }
}